package com.hrt.datasender.datacollect.serial.protocol;

import com.hrt.datasender.mq.model.SerialModel;
import com.hrt.serial.modbus.CRCException;
import com.hrt.serial.modbus.ModbusDataDecodeTTMB;
import com.hrt.serial.modbus.ModbusDataFrameDecoderBase;
import com.hrt.serial.modbus.MsgLengthException;

import java.util.ArrayList;
import java.util.Base64;
import java.util.List;

public class TextProtocol implements ISerialDataProtocol {

    private byte[] tempData;

    @Override
    public String getProtocolName() {
        return "文本协议";
    }

    @Override
    public List<SerialModel> decode(byte[] data, int datalength, String comNum) {
        /**
         * 文本协议的拆包原则：
         * 1、判断包头、包尾是否正常
         * 2、正常：进入解析数据环节
         * 3、包尾不正常：等待报文的发送
         * 4、包头不正常：清空数据，等待下一条报文
         */
        byte[] finalByteData = mergeData(data, datalength);
        String msg = new String(finalByteData);
        msg = msg.replaceAll("[\u0000]", "");
        msg = msg.trim();
        if(msg.startsWith("Z0,")){
            /**
             * 包头以Z0,开始，但没有包尾
             */
            if(!msg.endsWith("<ZEEI>")){
                setTempByteData(data, datalength);
                return null;
            }
        }
        else {
            /**
             * 包头不以Z0,开始
             */
            return null;
        }

        List<SerialModel> models = new ArrayList<>();
        SerialModel model = new SerialModel(finalByteData, comNum, null);
        models.add(model);
        return models;
    }

    public byte[] mergeData(byte[] curData, int datalength) {

        if (tempData == null) {
            tempData = new byte[0];
        }

        byte[] finalByteData = new byte[tempData.length + datalength];

        int tempDataLength = tempData.length;

        for (int i = 0; i < tempDataLength; i++) {
            finalByteData[i] = tempData[i];
        }

        for (int i = 0; i < datalength; i++) {
            finalByteData[tempDataLength + i] = curData[i];
        }

        /**
         * 清除临时数据 临时数据使用过一次后，必须要清除，否则会影响下一次数据的解析
         */
        tempData = null;

        return finalByteData;
    }

    /**
     * 用于处理分包的情况 把数据长度不足的数据缓存起来，等待下一批数据一起处理。
     *
     * @param data
     * @param datalength
     */
    protected void setTempByteData(byte[] data, int datalength) {

        tempData = new byte[datalength];
        for (int i = 0; i < datalength; i++) {
            tempData[i] = data[i];
        }
    }
}


